package com.xwaf.platform.system.api.util.netty;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xwaf.platform.common.api.exception.SystemException;
import com.xwaf.platform.system.api.request.netty.MethodInvokeMeta;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

/**
 * 
 * <p>
 * netty 通道
 * <p>
 * 
 * @author 李聪 <br>
 * @email xwaf_love@yeah.net <br>
 * @since JDK 1.8<br>
 * @date 2020年1月8日 上午9:02:30 <br>
 * @see 无<br>
 *      Copyright (c) 2020, xwaf_love@yeah.net All Rights Reserved.<br>
 */
public class ChannelUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(ChannelUtil.class);
	/**
	 * 用于记录c-s连接后建立的通道
	 */
	private static final Set<Channel> CHANNELS = new ConcurrentSkipListSet<>();
	/**
	 * 用于记录通道响应的结果集
	 */
	private static final Map<String, Object> RESULT_MAP = new ConcurrentHashMap<>();

	private ChannelUtil() {
	}

	/**
	 * 
	 * <p>
	 * 计算结果集（存储响应结果）
	 * <p>
	 * 
	 * @author 李聪 <br>
	 * @email xwaf_love@yeah.net <br>
	 * @since JDK 1.8<br>
	 * @date 2020年1月8日 上午9:46:27 <br>
	 * @see 无<br>
	 * @param key
	 *            唯一标识
	 * @param result
	 *            结果集
	 * @demo <br>
	 */
	public static void calculateResult(String key, Object result) {
		RESULT_MAP.put(key, result);
	}

	/**
	 * <p>
	 * 获取结果集的key
	 * <p>
	 * 
	 * @author 李聪 <br>
	 * @email xwaf_love@yeah.net <br>
	 * @since JDK 1.8<br>
	 * @date 2020年1月8日 上午9:46:49 <br>
	 * @see 无<br>
	 * @param key
	 *            保存的唯一标识
	 * @return 结果集的 key (通道标识)
	 * @demo <br>
	 */
	public static String getResultKey(String key) {
		return (String) getResult(key);
	}

	/**
	 * 
	 * <p>
	 * 根据结果集的 key 获取结果集
	 * <p>
	 * 
	 * @author 李聪 <br>
	 * @email xwaf_love@yeah.net <br>
	 * @since JDK 1.8<br>
	 * @date 2020年1月8日 上午9:47:13 <br>
	 * @see 无<br>
	 * @param key
	 *            结果集的key
	 * @return 结果集
	 * @demo <br>
	 */
	public static Object getResult(String key) {
		return RESULT_MAP.get(key);
	}

	/**
	 * 
	 * <p>
	 * 注册通道
	 * <p>
	 * 
	 * @author 李聪 <br>
	 * @email xwaf_love@yeah.net <br>
	 * @since JDK 1.8<br>
	 * @date 2020年1月8日 上午9:47:28 <br>
	 * @see 无<br>
	 * @param channel
	 *            通道
	 * @demo <br>
	 */
	public static void registerChannel(Channel channel) {
		ChannelId id = channel.id();
		LOGGER.info("{} -> [添加通道] {}", ChannelUtil.class.getName(), id);
		CHANNELS.add(channel);
	}

	/**
	 * 
	 * <p>
	 * 获取回调结果
	 * <p>
	 * 
	 * @author 李聪 <br>
	 * @email xwaf_love@yeah.net <br>
	 * @since JDK 1.8<br>
	 * @date 2020年1月8日 上午9:47:41 <br>
	 * @see 无<br>
	 * @param methodInvokeMeta
	 *            远程调用方法信息
	 * @param key
	 *            用于取结果的key值
	 * @demo <br>
	 */
	public static void remoteCall(MethodInvokeMeta methodInvokeMeta, String key) {
		LOGGER.info("{} -> [远程调用] ", ChannelUtil.class.getName());
		Iterator<Channel> iterator = CHANNELS.iterator();
		Channel channel;
		if (iterator.hasNext()) {
			channel = iterator.next();
		} else {
			LOGGER.error("{} -> [没有活跃的通道] ", ChannelUtil.class);
			throw new SystemException("没有活跃的通道");
		}
		// 将用于获取结果的key保存,以通道id为键
		String channelID = channel.id().asLongText();
		LOGGER.info("{} -> [保存获取结果的key] key - {} 通道id - {}", ChannelUtil.class, key, channelID);
		RESULT_MAP.put(channelID, key);
		ChannelFuture channelFuture = channel.writeAndFlush(methodInvokeMeta);
		// channelFuture.addListener(ChannelFutureListener.CLOSE);
	}

	public static void remove(Channel channel) {
		CHANNELS.remove(channel);
	}
}
